package org.vectrics.recruiter.struts.tag;

/**
 * Title: vectrics Server for Logging Description: Copyright: Copyright (c) 2001
 * Company: vectrics Software Inc. Service is Built In
 * 
 * @author Mike Moore
 * @version 1.0
 */
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;

import org.apache.ecs.MultiPartElement;
import org.apache.ecs.html.A;
import org.apache.ecs.html.IMG;
import org.apache.ecs.html.Input;
import org.apache.log4j.Category;
import org.vectrics.SystemException;
import org.vectrics.common.html.BorderTable;
import org.vectrics.common.html.Cell;
import org.vectrics.common.html.Form;
import org.vectrics.common.html.Row;
import org.vectrics.common.html.Table;
import org.vectrics.common.html.TextHelper;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.location.Location;
import org.vectrics.location.LocationComparator;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.struts.VectricsTagSupport;

/**
 * HTML table of Locations arranged hierarchically. If the user can change the
 * location settings for context types (select Locations for certain combo
 * boxes) then place the table in a form that is connected to an action that
 * will save the settings.
 * 
 * @author Mike Moore
 * 
 */
public abstract class LocationTreeTag extends VectricsTagSupport {

    private static final long serialVersionUID = -7878931254350589384L;

    private String domainId = null;

    static private Category log = Category.getInstance(LocationTreeTag.class);

    public static String TABLE_FONT = "subFont";

    private int depth = 2;

    private boolean needToDisplayForm() {
        return getContextTypes().size() > 0;
    }

    protected abstract String getFormSaveAction();

    protected abstract List getContextTypes();

    /**
     * Display the table of Locations arranged hierarchically. If the user can
     * change the location settings for context types (select Locations for
     * certain combo boxes) then place the table in a form that is connected to
     * an action that will save the settings.
     */
    @Override
    public String makeStartTag() {
        log.debug("doRender() called");
        MultiPartElement parentElement = null;
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        Form form = null;

        Table mainTable = new Table();
        if (needToDisplayForm()) {
            form = new Form();
            form.setAction(getFormSaveAction());
            form.addElement(mainTable);
            form.setMethod(Form.post);
            parentElement = form.getEcsForm();

        } else {
            parentElement = mainTable;
        }
        Row mainRow = mainTable.addRow();
        Cell mainCell = mainRow.addCell();

        Domain domain = getDomain();

        if (domain == null) {
            domain = ThreadProperties.getDomain();
        }

        Collection locationList = null;
        try {
            locationList = CoreServiceLocator.getLocationService().findTopLevelLocations(domain);
            if (locationList.size() == 0) {
                log.warn("Could not find top level locations for domain" + "\r\n - Domain = " + domain);
            }
        } catch (Exception ex) {
            log.error("Exception getting location list");
            throw new SystemException(ex);
        }

        if (locationList == null || locationList.size() == 0) {
            mainCell.addElement(TextHelper.getFont("stdFont", "<br><i>No Locations</i>"));
        } else {
            BorderTable listTable = new BorderTable();
            mainCell.addElement(listTable);
            listTable.setWidth("100%");
            Iterator iter = locationList.iterator();
            Row hdrRow = listTable.addRow();
            // Cell hdrCell = hdrRow.addCell();
            // hdrCell.addElement(TextHelper.getFont("smlTblHeader", "Code"));
            Cell hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.name")));
            hdrCell.setWidth(220);
            hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.only.description")));
            hdrCell.setWidth(150);
            hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.only.abbreviation")));
            hdrCell.setWidth(100);
            hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.add.children")));
            hdrCell.setWidth(80);
            hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.edit")));
            hdrCell.setWidth(80);
            hdrCell = hdrRow.addCell();
            hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("prompt.location.delete")));
            hdrCell.setWidth(80);

            Iterator contextIter = getContextTypes().iterator();
            while (contextIter.hasNext()) {
                String contextCode = (String) contextIter.next();
                hdrCell = hdrRow.addCell();
                hdrCell.addElement(TextHelper.getFont("smlTblHeader", this.getPhrase("location.context." + contextCode)));
                hdrCell.setWidth(80);

            }
            showLocations(locationList, 0, listTable, request);
        }
        if (needToDisplayForm()) {
            Input submitButton = new Input();
            submitButton.setType(Input.image);
            submitButton.setSrc("/hrs-intranet/dynagraphic/button.jpg?code=button.ok&caption=Save");
            submitButton.setBorder(0);
            submitButton.setName("submit");
            submitButton.setValue("submit");
            form.addElement(" <br /> ");
            form.addElement(submitButton);
            A aNewLocation = new A();
            aNewLocation.setHref("/hrs-intranet/admin/location/new.do");
            aNewLocation.setStyle(" border:0; ");
            IMG newButton = new IMG();
            newButton.setSrc("/hrs-intranet/dynagraphic/button.jpg?code=button.ok&caption=New%20Country");
            newButton.setName("submit");
            aNewLocation.addElement(newButton);
            form.addElement(aNewLocation);
        }
        String html = parentElement.toString();

        return html;
    }

    /**
     * Show the locations in a table
     * 
     * @param locations
     * @param indent
     * @param listTable
     * @param request
     */
    private void showLocations(final Collection locations, final int indent, final Table listTable,
            final HttpServletRequest request) {
        TreeSet sortedLocations = new TreeSet(new LocationComparator());
        sortedLocations.addAll(locations);
        Iterator iter = sortedLocations.iterator();
        while (iter.hasNext()) {
            Location location = (Location) iter.next();
            Row row = listTable.addRow();
            Cell cell = row.addCell();
            String indentStr = "";
            for (int i = 0; i <= indent; i++) {
                indentStr += "*&nbsp;";
            }
            cell.addElement(TextHelper.getFont(TABLE_FONT, indentStr + location.getName()));
            cell = row.addCell();

            if (location.getDescription() != null && !location.getDescription().trim().equals("")) {
                cell.addElement(TextHelper.getFont(TABLE_FONT, location.getDescription()));
            } else {
                cell.addElement(" &nbsp; &nbsp; &nbsp; ");
            }

            cell = row.addCell();

            if (location.getAbbreviation() != null && !location.getAbbreviation().trim().equals("")) {
                cell.addElement(TextHelper.getFont(TABLE_FONT, location.getAbbreviation()));
            } else {
                cell.addElement(" &nbsp; &nbsp; &nbsp; ");
            }

            cell = row.addCell();

            if (!location.getTypeCode().equalsIgnoreCase("city")) {
                A addChildLink = new A();
                addChildLink.setHref(request.getContextPath() + "/admin/location/addChild.do?parentId="
                        + location.getId());
                addChildLink.setClass("subLink");
                addChildLink.addElement(this.getPhrase("prompt.location.add.children"));
                cell.addElement(addChildLink);
            } else {
                cell.addElement(" &nbsp; &nbsp; ");
            }
            cell = row.addCell();

            A addEditLink = new A();
            addEditLink.setHref(request.getContextPath() + "/admin/location/edit.do?locationId=" + location.getId());
            addEditLink.setClass("subLink");
            addEditLink.addElement(this.getPhrase("prompt.location.edit"));
            cell.addElement(addEditLink);

            cell = row.addCell();

            A addDeleteLink = new A();
            addDeleteLink
                    .setHref(request.getContextPath() + "/admin/location/delete.do?locationId=" + location.getId());
            addDeleteLink.setClass("subLink");
            addDeleteLink.addElement(this.getPhrase("prompt.location.delete"));
            cell.addElement(addDeleteLink);

            if (indent + 1 <= depth) {
                showLocations(location.getChildren(), indent + 1, listTable, request);
            }

            Iterator contextIter = getContextTypes().iterator();
            while (contextIter.hasNext()) {
                String contextCode = (String) contextIter.next();
                boolean hasDomainLocation = CoreServiceLocator.getLocationService().hasDomainLocation(
                        ThreadProperties.getDomain(), location, contextCode);

                cell = row.addCell();
                Input input = new Input();
                input.setType(Input.checkbox);
                input.setName(contextCode + "_" + location.getId().toString());
                if (hasDomainLocation) {
                    input.setChecked(true);
                }
                cell.addElement(input);
                cell.setWidth(80);
            }

        }
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(final int depth) {
        this.depth = depth;
    }

    /**
     * The domain where context type settings will be made.
     * 
     * @return Returns the domainId.
     */
    public String getDomainId() {
        return domainId;
    }

    /**
     * @param domainId
     *            The domainId to set.
     */
    public void setDomainId(final String domainId) {
        this.domainId = domainId;
    }

    /**
     * Find the domain corresponding to the domainId property.
     * 
     * @return
     */
    public Domain getDomain() {
        return CoreServiceLocator.getSystemService().findDomain(new Long(getDomainId()));
    }

}
